<?php
namespace app\admin\logic;

use app\admin\model\RefundModel;
use app\api\logic\PayLogic;
use app\inter\logic\OrderLogic;
use my\Tools;
use think\Cache;
use think\Db;

class RefundLogic
{
    /**
     * 根据条件获取退款信息
     * @param $map
     * @param $field
     * @param $page
     * @param $limit
     * @return array|false
     * */
    public function getRefund($map,$field='a.*',$page=1,$limit=10)
    {
        $model = new RefundModel();
        return $model->getRefund($map,$field,$page,$limit);
    }

    /**
     * 根据条件获取退款数量
     * @param $map
     * @return int|false
     * */
    public function getRefundCount($map=array())
    {
        $model = new RefundModel();
        return $model->getRefundCount($map);
    }

    /**
     * 根据主键id获取退款信息
     * @param $id
     * @param $field
     * @param $type //根据类型判断id为某张表的主键id
     * @return array|false
     * */
    public function getRefundById($id,$field='a.*',$type='refund')
    {
        $model = new RefundModel();
        switch ($type){
            case 'refund':
                $map['a.id'] = $id;
                break;
            /*case 'scale':
                $map['b.id'] = $id;
                break;*/
            case 'order':
                $map['c.id'] = $id;
                break;
            case 'user':
                $map['d.id'] = $id;
                break;
            default:
                $map['a.id'] = $id;
                break;
        }
        return $model->searchRefund($map,$field);
    }

    /**
     * 自动处理城际订单退款
     * @param $refund //退款申请的信息
     * @return array
     * */
    public function autoRefund($refund)
    {
        $flag = true;//判断是否需要退款至第三方账户-----默认需要退款至第三方账户
        $poundage = 0;//手续费为零
        $user_money = $refund['user_money'];//余额支付的金额
        $award_money = $refund['award_money'];//赠送余额支付的金额
        $third_refund = $refund['third_price'];//第三方支付的金额
        $rate = $refund['force_cancel_rate'];//$refund['price_rate'];
        //该退款有相关退款收费标准
        if($rate){
            $poundage = ($refund['order_price']*100)*$rate/10000;//手续费--元
            //手续费比第三方支付的金额多,那么只要退款实际支付的金额和手续费之间的差额到用户余额即可
            if($poundage*100 >= $third_refund*100){
                //手续费比第三方支付的金额与余额支付的金额之和还要多
                if($poundage >= ($user_money+$third_refund)){
                    $award_money = (($award_money*100) - ($poundage*100 - $third_refund*100 - $user_money*100))/100;
                    $user_money = 0;
                }else{
                    $user_money = (($user_money*100) - ($poundage*100 - $third_refund*100))/100;
                }
                $third_refund = 0;
                $flag = false;
            }
            //手续费比第三方支付的金额少
            else{
                $third_refund = ($third_refund*100-$poundage*100)/100;
            }
        }
        ($poundage*100) > 0 && $refund['remark_recharge']="退款扣除手续费{$poundage}元";
        if($refund['paytool']==3){
            $flag = false ;
            $third_refund=0;
        }
        $refund['wallet_refund'] = ($user_money*100+$award_money*100)/100;
        $refund['user_money'] = $user_money;
        $refund['award_money'] = $award_money;
        $refund['third_refund'] = $third_refund;
        $refund['poundage'] = $poundage;
        $refund['flag'] = $flag;
        $refund['fact_refund_c'] = ($refund['wallet_refund']*100+$third_refund*100)/100;//计算获得的实际退款金额
        return $this->handleRefund($flag,$refund);
    }

    /**
     * 由财务指定退款金额处理城际订单退款
     * @param $refund //退款申请的信息
     * @return array
     * */
    public function appointRefund($refund)
    {
        $flag = true;//判断是否需要退款至第三方账户-----默认需要退款至第三方账户
        $poundage = (($refund['need_price']*100) - ($refund['fact_money_hand']*100))/100;//手续费为零
        $user_money = $refund['user_money'];//余额支付的金额
        $award_money = $refund['award_money'];//赠送余额支付的金额
        $third_refund = $refund['third_price'];//第三方支付的金额
        if($poundage*100 >= $third_refund*100){
            //手续费比第三方支付的金额与余额支付的金额之和还要多
            if($poundage >= ($user_money+$third_refund)){
                $award_money = (($award_money*100) - ($poundage*100 - $third_refund*100 - $user_money*100))/100;
                $user_money = 0;
            }else{
                $user_money = (($user_money*100) - ($poundage*100 - $third_refund*100))/100;
            }
            $third_refund = 0;
            $flag = false;
        }
        //手续费比第三方支付的金额少
        else{
            $third_refund = ($third_refund*100-$poundage*100)/100;
        }
        ($poundage*100) > 0 && $refund['remark_recharge']="退款扣除手续费{$poundage}元";
        if($refund['paytool']==3){
            $flag = false ;
            $third_refund=0;
        }
        $refund['wallet_refund'] = ($user_money*100+$award_money*100)/100;
        $refund['user_money'] = $user_money;
        $refund['award_money'] = $award_money;
        $refund['third_refund'] = $third_refund;
        $refund['poundage'] = $poundage;
        $refund['flag'] = $flag;;
        $refund['fact_refund_c'] = ($refund['wallet_refund']*100+$third_refund*100)/100;//计算获得的实际退款金额
        return $this->handleRefund($flag,$refund);
    }

    /**
     * 处理退款---20180910不用
     * @param $refund //退款申请的信息
     * @return array
     */
    public function handleRefundScrap($refund)
    {
        switch($refund['paytool']){
            //支付宝
            case 1:
            case 4:
                $config = config('aliPay');
                return $this->aliRefundByInterOrder($config,$refund);
                break;
            //微信
            case 2:
            case 5:
                $config = config('wechatPay');
                return $this->wxRefundByInterOrder($config,$refund);
                break;
            default:
                return array('status'=>2,'msg'=>'支付工具参数错误');
        }
    }

    /**
     * 处理退款
     * @param $flag //是否需要退至第三方
     * @param $refund //退款申请的信息
     * @return array
     */
    private function handleRefund($flag,$refund)
    {
        if($flag){
            switch($refund['paytool']){
                //支付宝
                case 1:
                case 4:
                    $config = config('aliPay');
                    return $this->aliRefundByInterOrder($config,$refund);
                    break;
                //微信
                case 2:
                case 5:
                    $config = config('wechatPay');
                    return $this->wxRefundByInterOrder($config,$refund);
                    break;
                default:
                    return array('status'=>2,'msg'=>'支付工具参数错误');break;
            }
        }
        //使用余额支付,将退款直接返回钱包 或 退款的手续费高于第三方支付的金额
        return $this->updateRefund('',$refund);
    }

    /**
    * 微信退款
    * @param $config //微信退款参数
    * @param $data //退款申请的信息
    * @return array
    * */
    private function wxRefundByInterOrder($config,$data)
    {
        $order_sn = $data['order_sn'];
        $need_price = $data['third_price']*100 ;//支付在微信上的金额
        $refund_sn = $data['refund_sn'];
        //计算好的退款金额减去用户余额支付的金额为实际第三方退款的金额
        $refund_fee = $data['third_refund']*100;
        /*$result = Tools::wxRefund($config,$order_sn,$need_price,$refund_sn,$refund_fee);
        if($result['return_code']=='SUCCESS'){
            if($result['result_code'] == 'SUCCESS'){
                $return = $this->updateRefund($result,$data);
            }
            else{
                $return = array('status'=>2,'msg'=>$result['err_code_des']);
            }
        }
        else{
            $return = array('status'=>2,'msg'=>$result['return_msg']);
        }*/
        $result = Tools::wxRefundJava($order_sn,$need_price,$refund_sn,$refund_fee);
        Cache::set('testWx',$result['data']);
        if($result['status']==200){
            $return = $this->updateRefund($result['data'],$data);
        }
        else{
            $return = array('status'=>2,'msg'=>$result['msg']);
        }
        return $return;
    }

    /**
     * 阿里退款
     * @param $config //阿里退款参数
     * @param $data //退款申请的信息
     * @return array
     * */
    private function aliRefundByInterOrder($config,$data)
    {
        /*$result = Tools::aliRefund($config,$data['order_sn'],$data['refund_sn'],$data['third_refund']);
        if($result['code']==10000){
            $return = $this->updateRefund($result,$data);
        }
        else{
            $return = array('status'=>2,'msg'=>$result['sub_msg']);
        }*/
        $result = Tools::aliRefundJava($data['order_sn'],$data['refund_sn'],$data['third_refund']);
        Cache::set('testAli',$result['data']);
        if($result['status']==200){
            $return = $this->updateRefund($result['data'],$data);
        }
        else{
            $return = array('status'=>2,'msg'=>$result['msg']);
        }
        return $return;
    }

    /**
     * 更新退款申请的信息---20180910不用
     * @param $result
     * @param $data
     * @return  array
     * */
    private function updateRefundScrap($result,$data)
    {
        $order_logic = new OrderLogic();
        /*****************更新对应订单状态*************************/
        $data_common['order_status'] = 25;//退款成功
        $data_common['id'] = $data_user_recharge['common_id'] = $data['common_id'];//订单id
        $order_logic->renewOrderCommon(array(),$data_common);
        /*****************退款需要更新的数据*************************/
        $map_refund['id'] = $data['id'];
        $data_refund['is_handle'] = 1;//已处理
        /*****************增加用户账户变动记录*************************/
        $data_user_recharge['uid'] = $data['member_id'];
        $data_user_recharge['money'] = $data['third_refund']*100;
        $data_user_recharge['out_trade_no'] = $data['refund_sn'];
        $data_user_recharge['common_id'] = $data['common_id'];
        $data_user_recharge['type'] = $data['paytool'];
        $data_user_recharge['money_statement'] = 4;//退款
        $data_user_recharge['remark'] = "用户退款--第三方支付金额";//退款或扣款时的说明
        /*****************增加用户账户变动记录*************************/
        switch($data['paytool']){
            //支付宝
            case 1:
            case 4:
                $data_refund['handle_time'] = $data_user_recharge['time'] = $result['gmtRefundPay']/1000;//strtotime($result['gmt_refund_pay'])
                break;
            //微信
            case 2:
            case 5:
                $data_refund['handle_time'] = $data_user_recharge['time'] = time();//退款时间
                break;
            default:
                return array('status'=>2,'msg'=>'支付工具参数错误');
                break;
        }
        $model = new RefundModel();
        Db::table('xm_user_recharge')->insert($data_user_recharge);
        $res = $model->updateRefund($map_refund,$data_refund);
        if(empty($res)){
            return array('status'=>2,'msg'=>'修改错误');
        }
        /******************给用户发送信息***********************/
        $data_msg['uid'] = $info['uid'] = $data['member_id'];
        $data_msg['title'] = "退款成功";
        $data_msg['content'] = "您的退款申请已成功处理,订单号{$data['order_sn']},申请退款{$data['refund_money']}元,实际退款{$data_refund['fact_money']}元";
        $data_msg['send_time'] = time();
        $data_msg['type'] = 3;
        $data_msg['order_type'] = 3;
        $info['type'] = 'user';
        $info['registration_id'] = Db::table('xm_user')->where('uid',$data['member_id'])->value('registration_id');
        Db::table('xm_passenger_message')->insert($data_msg);
        $info['registration_id'] && Tools::JPush($data_msg['title'],$data_msg['content'],$info['registration_id'],'user');
        /******************给用户发送信息***********************/
        return array('status'=>1,'msg'=>'退款成功');
    }

    /**
     * 更新退款申请的信息
     * @param $result
     * @param $data
     * @return  array
     * */
    private function updateRefund($result,$data)
    {
        $order_logic = new OrderLogic();
        $pay_logic = new PayLogic();
        /*****************更新对应订单状态*************************/
        $data_common['order_status'] = 25;//退款成功
        $data_common['id'] = $data_user_recharge['common_id'] = $data['common_id'];//订单id
        $order_logic->renewOrderCommon(array(),$data_common);
        /*****************退回优惠券*************************/
        $data_coupon['coupon_id'] = $data['coupon_id'];
        $data_coupon['is_use'] = 2;//改为未使用
        $data['coupon_id']&&$order_logic->renewCoupon(array(),$data_coupon);
        /*****************将用该退回的用户余额转至用户余额表中*************************/
        $data['user_money']*100 && $pay_logic->changeUserWallet($data['user_money']*100,$data['member_id']);
        $data['award_money']*100 && $pay_logic->changeUserWallet($data['award_money']*100,$data['member_id'],1,'return_money');
        /*****************退款需要更新的数据*************************/
        $map_refund['id'] = $data['id'];
        $data_refund['fact_money'] = $data['fact_refund_c'];
        $data_refund['wallet_refund'] = $data['wallet_refund'];
        $data_refund['third_refund'] = $data['third_refund'];
        $data_refund['poundage'] = $data['poundage'];
        $data_refund['is_handle'] = 1;//已处理
        $tip = '';
        $data['user_money']*100 && $tip .= "退至余额{$data['user_money']}元<br>";
        $data['award_money']*100 && $tip .= "退至赠送余额{$data['award_money']}元<br>";
        $data['third_refund']*100 && $tip .= "退至第三方{$data['third_refund']}元<br>";
        $data_refund['remark'] = $data['remark_p'].$tip.$data['remark_recharge']."<br>";//已处理
        /*****************增加用户账户变动记录*************************/
        $data_user_recharge['uid'] = $data['member_id'];
        $data_user_recharge['money'] = $data['fact_refund_c']*100;
        $data_user_recharge['out_trade_no'] = $data['refund_sn'];
        $data_user_recharge['type'] = $data['paytool'];
        $data_user_recharge['money_statement'] = 4;//退款
        $data_user_recharge['status'] = 1;
        $data_user_recharge['remark'] = $tip.$data['remark_recharge'];//退款或扣款时的说明
        /*****************增加用户账户变动记录*************************/
        $model = new RefundModel();
        $data_refund['handle_time'] = $data_user_recharge['time'] = time();//退款时间
        /*switch($data['paytool']){
            //支付宝
            case 1:
            case 4:
            $data_refund['handle_time'] = $data_user_recharge['time'] = $result['flag']?$result['gmtRefundPay']/1000:time();//strtotime($result['gmt_refund_pay'])
                break;
            //微信
            case 2:
            case 5:
            default:
            $data_refund['handle_time'] = $data_user_recharge['time'] = time();//退款时间
                break;
        }*/
        $res = $model->updateRefund($map_refund,$data_refund);
        if(empty($res)){
            return array('status'=>2,'msg'=>'修改错误');
        }
        Db::table('xm_user_recharge')->insert($data_user_recharge);
        /******************给用户发送信息***********************/
        $data_msg['uid'] = $info['uid'] = $data['member_id'];
        $data_msg['title'] = "退款成功";
        $data_msg['content'] = $data['poundage']*100?"您的退款申请已成功处理,订单号{$data['order_sn']},申请退款{$data['refund_money']}元,实际退款{$data_refund['fact_money']}元,".$data['remark_recharge']:
            "您的退款申请已成功处理,订单号{$data['order_sn']},申请退款{$data['refund_money']}元,实际退款{$data_refund['fact_money']}元";
        $data_msg['send_time'] = time();
        $data_msg['type'] = 3;
        $data_msg['order_type'] = 3;
        $info['type'] = 'user';
        $info['registration_id'] = Db::table('xm_user')->where('uid',$data['member_id'])->value('registration_id');
        Db::table('xm_passenger_message')->insert($data_msg);
        $info['registration_id'] && Tools::JPush($data_msg['title'],$data_msg['content'],$info['registration_id'],'user');
        /******************给用户发送信息***********************/
        return array('status'=>1,'msg'=>'退款成功');
    }

    /**
     * 退款查询
     * @param $order_common
     * @return  mixed
     */
    public function refundQuery($order_common)
    {
        $refund = $this->getRefundById($order_common['id'],'a.*,c.third_price','order');
        if($refund['is_handle']==2){
            return array('status'=>0,'msg'=>'该订单退款仍在处理中');
        }
        $refund['order_sn'] = $order_common['order_sn'];
        $refund['paytool'] = $order_common['paytool'];
        switch ($order_common['paytool']){
            //支付宝
            case 1:
            case 4:
                $config = config('aliPay');
                return $this->aliRefundQuery($config,$refund);
                break;
            //微信
            case 2:
            case 5:
                $config = config('wechatPay');
                return $this->wxRefundQuery($config,$refund);
                break;
            default:
                $refund['need_price'] = $order_common['need_price'];
                return array('status'=>1,'data'=>$refund);
                break;
        }
    }

    /**
     * 微信退款查询
     * @param $config
     * @param $refund
     * @return  mixed
     */
    private function wxRefundQuery($config,$refund)
    {
        /*$result = Tools::wxRefundQueryScrap($config,$refund['refund_sn']);
        if($result['return_code']=='SUCCESS'){
            if($result['result_code'] == 'SUCCESS'){
                //$result = array_merge($result,$refund);
                $result['total_fee'] = $result['total_fee']/100;
                $result['refund_fee'] = $result['refund_fee']/100;
                $return = array('status'=>1,'data'=>$result);
            }
            else{
                $return = array('status'=>0,'msg'=>$result['err_code_des']);
            }
        }
        else{
            $return = array('status'=>0,'msg'=>$result['return_msg']);
        }*/
        $result = Tools::wxRefundQueryJava($refund['refund_sn']);
        if($result['status']==200){
            foreach ($result['data']['refundRecords'] as $val){
                $refund['refund_fee'] += $val['refundFee'];
            }
            $refund['total_fee'] = $result['data']['totalFee']/100;
            $refund['refund_fee'] = $refund['refund_fee']/100;
            $return = array('status'=>1,'data'=>$refund);
        }
        else{
            $return = array('status'=>0,'msg'=>$result['msg']);
        }
        return $return;
    }

    /**
     * 支付宝退款查询
     * @param $config
     * @param $refund
     * @return  mixed
     */
    private function aliRefundQuery($config,$refund)
    {
        /*$result = Tools::aliRefundQuery($config,$refund['order_sn'],$refund['refund_sn']);
        if($result['code']==10000){
            $result = array_merge($result,$refund);
            $return = array('status'=>1,'data'=>$result);
        }
        else{
            $return = array('status'=>0,'msg'=>$result['sub_msg']);
        }*/
        $result = Tools::aliRefundQueryJava($refund['order_sn'],$refund['refund_sn']);
        if($result['status']==200){
            $refund['refund_amount'] = $result['data']['refundAmount'];
            $refund['total_amount'] = $result['data']['totalAmount'];
            $return = array('status'=>1,'data'=>$refund);
        }
        else{
            $return = array('status'=>0,'msg'=>$result['msg']);
        }
        return $return;
    }
}
